<template>
  <div style="height: 800px; width: 100%; background-color: #ededed">
    <div class="wrap">
      <!-- 头部 -->
      <div class="titleBox">
        <img
          src="https://img-qn-2.51miz.com/preview/element/00/01/27/97/E-1279706-3813EBF9.jpg!/quality/90/unsharp/true/compress/true/format/jpg/fh/320"
          alt=""
          class="head_portrait"
          style="margin-left: 20px; margin-right: 20px"
        >
        <span style="color: #fff">官方客服</span>
        <!-- 在线状态弹框 -->
        <el-popover placement="bottom" trigger="click">
          <div class="stateBox2" @click="uploadState(1)">
            <span class="state1" />
            <span class="stateText">在线</span>
          </div>
          <div class="stateBox2" @click="uploadState(2)">
            <span class="state2" />
            <span class="stateText">离线</span>
          </div>
          <div class="stateBox2" @click="uploadState(3)">
            <span class="state3" />
            <span class="stateText">忙碌</span>
          </div>
          <div class="stateBox2" @click="uploadState(4)">
            <span class="state4" />
            <span class="stateText">退出</span>
          </div>
          <div v-if="state == 1" slot="reference" class="stateBox">
            <span class="state1" />
            <span class="stateText">在线</span>
          </div>
          <div v-if="state == 2" slot="reference" class="stateBox">
            <span class="state2" />
            <span class="stateText">离线</span>
          </div>
          <div v-if="state == 3" slot="reference" class="stateBox">
            <span class="state3" />
            <span class="stateText">忙碌</span>
          </div>
        </el-popover>
        <h1 style="color: white;margin-left: 32%;">{{ sender }}</h1>
      </div>
      <!-- 底部 -->
      <div class="infoBox">
        <!-- 左边用户列表 -->
        <div class="userList">
          <div class="searchBox">
            <el-input
              v-model="search"
              placeholder="请输入内容"
              class="input-with-select"
              size="mini"
              @input="inquire"
            >
              <i
                slot="suffix"
                class="el-icon-search el-input__icon"
                @click="handleIconClick"
              />
            </el-input>
            <el-button
              icon="el-icon-plus"
              size="mini"
              type="primary"
              @click="dialogVisible = true"
            />
          </div>
          <div class="userListBox">
            <div
              v-for="(item, index) in userListData"
              :key="index"
              :class="item.id == act ? 'userFlexAct' : 'userFlex'"
              @click="getAct(item, index)"
            >
              <div>
                <img
                  :src="item.url"
                  alt="头像"
                  class="head_portrait2"
                  style="margin-left: 20px"
                >
              </div>
              <div style="margin-right: 40px">
                <el-tooltip
                  :content="item.sender"
                  placement="bottom"
                  effect="light"
                >
                  <div style="color: #565656" class="sender">
                    {{ item.sender }}
                  </div>
                </el-tooltip>
                <div class="userInfo">{{ item.content }}</div>
              </div>
              <div style="margin-right: 10px; font-size: 8px; color: #ccc">
                {{ item.time }}
              </div>
            </div>
          </div>
        </div>
        <!-- 右边输入框和信息展示 -->
        <div class="infoList">
          <!-- 信息 -->
          <div id="box" ref="scrollBox" class="infoTop">
            <div
              v-for="(item, index) in userInfoList"
              :key="index"
              :class="
                item.position == 'left' ? 'chatInfoLeft' : 'chatInfoRight'
              "
            >
              <img
                v-if="item.position == 'left'"
                :src="url"
                class="head_portrait2"
              >
              <img
                v-else-if="item.position == 'right'"
                src="https://img-qn-2.51miz.com/preview/element/00/01/27/97/E-1279706-3813EBF9.jpg!/quality/90/unsharp/true/compress/true/format/jpg/fh/320"
                class="head_portrait2"
              >
              <!-- <img :src="item.url" alt="头像" class="head_portrait2"> -->
              <div :class="item.position == 'left' ? 'chatLeft' : 'chatRight'">
                <div class="text">
                  <div v-if="item.msgType== 'text'">{{ item.content }}</div>
                  <div v-else-if="item.msgType == 'image'">
                    <img class="chatImage" :src="item.content" @click="handlePictureCardPreview(item.content)">
                  </div>
                </div>
              </div>
            </div>
          </div>
          <!-- 输入框 -->
          <div class="infoBottom">
            <div class="infoIcon">
              <el-upload
                class="upload-demo"
                action="http://localhost:8000/fileUpload"
                :show-file-list="false"
                :on-success="handleAvatarSuccess"
                :auto-upload="true"
              >
                <i
                  class="el-icon-picture-outline-round"
                />
              </el-upload>

              <el-popover
                v-model="visible"
                placement="top"
                trigger="hover"
              >
                <div class="expression">
                  <button v-for="item,index in arr1" v-show="expression" :key="index" class="expression_div" @click="emote(item)">{{ item }}</button>
                </div>
                <el-button slot="reference" style="background-color: rgb(242,242,242); border: transparent;font-size: 20px;">😉</el-button>
              </el-popover>
              <!-- <i class="el-icon-setting" @click="extend('设置')" /> -->

              <!-- <i class="el-icon-sell" @click="extend('发送商品')" /> -->
              <!-- <i class="el-icon-chat-dot-round" @click="extend('聊天记录')" /> -->
              <!-- <i class="el-icon-more-outline" @click="extend('更多选项')" /> -->
            </div>
            <textarea
              v-model="textarea"
              type="textarea"
              class="infoInput"
              :disabled="isshow == 1 ? false : true"
              @keydown.enter.exact="handlePushKeyword($event)"
              @keyup.ctrl.enter="lineFeed"
            />
            <div
              v-show="isshow == 1 ? true : false"
              class="fasong"
              @click="setUp"
            >
              发送
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- 搜索框边 + 号弹框 -->
    <el-dialog
      title="选择需要添加的联系人"
      :visible.sync="dialogVisible"
      width="30%"
      :modal="false"
    >
      <span>自定义页面，还没想好写什么功能</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button
          type="primary"
          @click="dialogVisible = false"
        >确 定</el-button>
      </span>
    </el-dialog>
    <el-dialog :visible.sync="dialogVisible2">
      <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
  </div>
</template>

<script>
import { getChatRecords, getChatList } from '@/api/chat'
export default {
  data() {
    return {
      dialogImageUrl: '',
      // lockReconnect: false, // 是否真正建立连接
      // timeout: 10 * 1000, // 30秒一次心跳
      // timeoutObj: null, // 心跳心跳倒计时
      // serverTimeoutObj: null, // 心跳倒计时
      timeoutnum: null, // 断开 重连倒计时
      toName: '', // 接受者
      // 在线状态
      state: 1,
      msgType: 'text',
      dialogVisible2: false,
      // 搜索用户
      search: '',
      sender: '',
      object: '',
      expression: true,
      visible: false,
      arr1: ['😁', '😂', '😃', '😄', '😅', '😆', '😉', '😊', '😋', '😎', '😍', '😘', '😚', '😐', '😶', '😏', '😣', '😥', '😪', '😫', '😌', '😜', '😝', '😒', '😓', '😔', '😲', '☹️', '😖', '😞', '😤', '😢', '😭', '😨', '😩', '😰', '😱', '😳', '😵', '😡', '😠', '😷', '😇', '😈', '👿', '👹', '👺', '💀', '👻', '👽', '😺', '😸', '😹', '😻', '😼', '😽', '🙀', '😿', '😾', '👐', '🙌', '👏', '👍', '👎', '👊', '✊', '✌️', '👌', '👈', '👉', '👆', '👇', '☝️', '✋', '👋', '💪', '✍️', '🙏', '🐶', '🐱', '🐭', '🐹', '🐰', '🐻', '🐼', '🐨', '🐯', '🐮', '🐷', '🐽', '🐸', '🐵', '🙈', '🙉', '🙊', '🐒', '🐔', '🐧', '🐦', '🐤', '🐣', '🐥', '🐺', '🐗', '🐴', '🐝', '🐌', '🐚', '🐞', '🐜', '🐢', '🐍', '🐙', '🐡', '🐠', '🐟', '🐬', '🐳', '🐘', '🐫', '🐎', '🐑', '🐩', '🐾', '🐲', '🌵', '🎄', '🌴', '🌱', '🌿', '☘️', '🍀', '🎍', '🎋', '🍃', '🍂', '🍁', '🍄', '🌾', '💐', '🌷', '🌹', '🌺', '🌸', '🌼', '🌻', '🌛', '🌕', '🌑', '🌓', '🌔', '🌙', '🌏', '💫', '⭐️', '🌟', '✨', '⚡️', '☄️', '💥', '🔥', '🌈', '☀️', '⛅️', '☁️', '❄️', '☃️', '⛄️', '🌬', '💨', '💧', '💦', '☔️', '☂️', '🌊'], // 表情包
      // 用户列表渲染数据
      userListData: [],
      // 用户列表筛选数据
      userListDatas: [],
      // 用户点击选中变色
      act: Number,
      // 加号弹框
      dialogVisible: false,
      // 历史信息
      userInfoList: [],
      // 输入框
      textarea: '',
      // 滚动条距离顶部距离
      scrollTop: 0,
      // 发送和输入显隐
      isshow: 0
    }
  },
  created() {
    // this.getList()
  },
  beforeDestroy() {
    // 离开页面后关闭连接
    // this.ws.close()
    // 清除时间
    clearTimeout(this.timeoutObj)
    clearTimeout(this.serverTimeoutObj)
  },
  // socket的用法
  sockets: {
    // 连接
    connect() {
      console.log('连接成功')
    },
    // 断开
    disconnect() {
      console.log('断开连接')
    },
    // 登记
    chatLogin(data) {
      console.log(data, 183)
    },
    // 接收消息
    message(data) {
      console.log('ws收到服务器消息', data)
      console.log(this.userInfoList)
      if (this.toName !== '') {
        this.userInfoList.push({
          url: data[0].fromUserFace,
          sender: data[0].name,
          content: data[0].content,
          msgType: data[0].msgType,
          time: data[0].time,
          object: data[0].object,
          position: 'left'
        })
      }
      // console.log(this.userInfoList, 273)
      // this.List()
      for (var i = 0; i < this.userListData.length; i++) {
        console.log('已刷新', this.userListData[i].chatListId, this.userListData[i].object)
        console.log('已刷新2', data[0].name, data[0].object)
        if (this.userListData[i].chatListId === data[0].name && this.userListData[i].object === data[0].object) {
          this.userListData[i].content = data[0].content
          console.log(279)
          this.$forceUpdate()
        }
      }
      this.setPageScrollTo()
      setTimeout((res) => {
        this.setPageScrollTo()
        // 页面滚动条距离顶部高度等于这个盒子的高度
        this.$refs.scrollBox.scrollTop = this.$refs.scrollBox.scrollHeight
      }, 1000)
    },
    messagetip(data) {
      console.log(data, 504)
      for (var i = 0; i < this.userListData.length; i++) {
        console.log('已刷新', this.userListData[i].chatListId, this.userListData[i].object)
        console.log('已刷新2', data[0].name, data[0].object)

        if (this.userListData[i].chatListId === data[0].name && this.userListData[i].object === data[0].object) {
          this.userListData[i].content = data[0].content
          console.log(279)
        }
      }
      this.$forceUpdate()
    // this.getchatarr()
    }
  },
  mounted() {
    this.$socket.emit('chatLogin', {
      staffAcc: '客服'
    })
    this.List()
  },
  methods: {
    emote(item) {
      this.textarea += item
    },
    async getList() {
      this.userInfoList = []
      const chatlist = {
        toName: this.toName,
        object: this.object
      }
      const res = await getChatRecords(chatlist)
      if (res.code !== 200) return this.$message.error('查找失败')
      if (res.code === 200) {
        for (let i = 0; i < res.data.length; i++) {
          this.userInfoList.push({
            // url: 'res.data[i].fromUserFace',
            sender: res.data[i].sender,
            receiver: res.data[i].receiver,
            content: res.data[i].content,
            msgType: res.data[i].msgType,
            time: res.data[i].time,
            position: res.data[i].position
          })
        }
      }
    },
    List() {
      // 左侧列表
      this.userListData = []
      getChatList().then(res => {
        console.log(res.data)
        for (let i = 0; i < res.data.length; i++) {
          this.userListData.push({
            chatid: res.data[i].id,
            chatListId: res.data[i].chatListId,
            url: res.data[i].url,
            sender: res.data[i].userName,
            content: res.data[i].info,
            time: res.data[i].timer,
            object: res.data[i].object
          })
          this.userListDatas.push({
            chatid: res.data[i].id,
            chatListId: res.data[i].chatListId,
            url: res.data[i].url,
            sender: res.data[i].userName,
            content: res.data[i].info,
            time: res.data[i].timer,
            object: res.data[i].object
          })
        }
      })
    },
    // 切换客服状态
    uploadState(state) {
      if (state !== 4) {
        this.state = state
      } else {
        this.$confirm('是否退出登录?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then(() => {
            this.$message({
              type: 'success',
              message: '退出成功!'
            })
          })
          .catch(() => {
            this.$message({
              type: 'content',
              message: '已取消退出'
            })
          })
      }
    },
    // 搜索icon
    handleIconClick() {
      console.log(1)
    },
    // 点击用户
    getAct(val, index) {
      console.log(val, 537)
      this.$socket.emit('onchat', {
        name: val.chatListId,
        object: val.object
      })
      this.object = val.object
      this.toName = val.chatListId
      this.sender = val.sender
      this.url = val.url
      this.isshow = 1
      // 点击用户切换数据时先清除监听滚动事件，防止出现没有历史数据的用户，滚动条为0，会触发滚动事件
      this.$refs.scrollBox.removeEventListener('scroll', this.srTop)
      // 点击变色
      this.act = val.id
      // 清空消息数组
      this.userInfoList = []
      // 模拟一下点击用户出现历史记录的样子，实际开发中是axios请求后数组赋值然后调用setPageScrollTo
      if (val.sender === this.sender) {
        this.getList()
        // 直接调用不生效：因为你历史数据刚给，渲染的时候盒子高度还没有成型，所以直接调用拿不到，用个定时器让他在下一轮循环中调用，盒子就已经生成了
        setTimeout((res) => {
          this.setPageScrollTo()
          // 页面滚动条距离顶部高度等于这个盒子的高度
          this.$refs.scrollBox.scrollTop = this.$refs.scrollBox.scrollHeight
        }, 1000)
      }
    },
    // 模糊搜索用户
    inquire() {
      const fuzzy = this.search
      if (fuzzy) {
        this.userListData = this.userListDatas.filter((item) => {
          return item.sender.includes(fuzzy)
        })
      } else {
        this.userListData = this.userListDatas
      }
    },
    // 发送
    setUp() {
      console.log('发送内容:', this.textarea)
      this.userInfoList.push({
        url: 'https://img2.baidu.com/it/u=2859542338,3761174075&fm=253&fmt=auto&app=138&f=JPEG?w=501&h=500',
        sender: this.toName,
        content: this.textarea,
        msgType: this.msgType,
        time: '2022/8/1',
        position: 'right'
      })
      this.$socket.emit('chat_msg', {
        url: 'https://img-qn-2.51miz.com/preview/element/00/01/27/97/E-1279706-3813EBF9.jpg!/quality/90/unsharp/true/compress/true/format/jpg/fh/320',
        name: '客服',
        content: this.textarea,
        msgType: this.msgType,
        toname: this.toName,
        time: '2022/8/1',
        position: 'right',
        object: 'user'
      })
      this.textarea = ''
      this.List()
      // 页面滚动到底部
      setTimeout((res) => {
        this.setPageScrollTo()
        // 页面滚动条距离顶部高度等于这个盒子的高度
        this.$refs.scrollBox.scrollTop = this.$refs.scrollBox.scrollHeight
      }, 1000)
    },
    // 图片上传成功
    handleAvatarSuccess(res, file) {
      this.msgType = 'image'
      console.log(res, 123, file)
      this.textarea = res.data
      this.setUp()
      this.msgType = 'text'
    },
    // 点击放大图片
    handlePictureCardPreview(imgPath) {
      this.dialogImageUrl = imgPath
      this.dialogVisible2 = true
    },
    // 监听键盘回车阻止换行并发送
    handlePushKeyword(event) {
      this.msgType = 'text'
      console.log(event)
      if (event.keyCode === 13) {
        event.preventDefault() // 阻止浏览器默认换行操作
        this.setUp() // 发送文本
        return false
      }
    },
    // 监听按的是ctrl + 回车，就换行
    lineFeed() {
      console.log('换行')
      this.textarea = this.textarea + '\n'
    },
    // 点击icon
    extend(val) {
      alert('你点击了：' + val)
    },
    // 滚动条默认滚动到最底部
    setPageScrollTo(s, c) {
      // 获取中间内容盒子的可见区域高度
      this.scrollTop = document.querySelector('#box').offsetHeight
      setTimeout((res) => {
        // 加个定时器，防止上面高度没获取到，再获取一遍。
        if (this.scrollTop !== this.$refs.scrollBox.offsetHeight) {
          this.scrollTop = document.querySelector('#box').offsetHeight
        }
      }, 100)
      // scrollTop：滚动条距离顶部的距离。
      // 把上面获取到的高度座位距离，把滚动条顶到最底部
      this.$refs.scrollBox.scrollTop = this.scrollTop
      // 判断是否有滚动条,有滚动条就创建一个监听滚动事件，滚动到顶部触发srTop方法
      if (this.$refs.scrollBox.scrollTop > 0) {
        this.$refs.scrollBox.addEventListener('scroll', this.srTop)
      }
    },
    // 滚动条到达顶部
    srTop() {
      // 判断：当滚动条距离顶部为0时代表滚动到顶部了
      if (this.$refs.scrollBox.scrollTop === 0) {
        // 逻辑简介：
        // 到顶部后请求后端的方法，获取第二页的聊天记录，然后插入到现在的聊天数据前面。
        // 如何插入前面：可以先把获取的数据保存在 A 变量内，然后 this.userInfoList=A.concat(this.userInfoList)把数组合并进来就可以了

        // 拿聊天记录逻辑:
        // 第一次调用一个请求拉历史聊天记录，发请求时参数带上页数 1 传过去，拿到的就是第一页的聊天记录，比如一次拿20条。你显示出来
        // 然后向上滚动到顶部时，触发新的请求，在请求中把分页数先 +1 然后再请求，这就拿到了第二页数据，然后通过concat合并数组插入进前面，依次类推，功能完成！
        alert('已经到顶部了')
      }
    }

  }
}
</script>

<style scoped>
.wrap {
  height: 80%;
  /* width: 90%; */
  background-color: #f2f2f2;
  margin: auto;
  /* transform: translateY(10%); */
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
  border-radius: 10px;
}
.titleBox {
  height: 10%;
  width: 100%;
  background-image: linear-gradient(to right, #1e76bc, #69a3d5);
  display: flex;
  align-items: center;
  border-top-right-radius: 10px;
  border-top-left-radius: 10px;
}
.infoBottom {
  height: 30%;
  display: flex;
  flex-direction: column;
}
/* 输入框 */
.infoInput {
  height: 58%;
  width: 100%;
  border: none;
  resize: none;
  padding: 10px;
  box-sizing: border-box;
  background-color: #f2f2f2;
  color: #434343;
}
.fasong {
  height: 30px;
  width: 80px;
  background-color: #e8e8e8;
  text-align: center;
  line-height: 30px;
  border-radius: 4px;
  color: #58df4d;
  margin-top: 1%;
  align-self: flex-end;
  margin-right: 20px;
  cursor: pointer;
}
.infoIcon {
  height: 40px;
  width: 100%;
  display: flex;
  align-items: center;
}
.infoIcon i {
  font-size: 24px;
  color: #676767;
  margin-left: 15px;
  cursor: pointer;
}
/* 头像 */
.head_portrait {
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
}
.head_portrait2 {
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
}
.stateBox {
  margin-left: 20px;
  padding: 1px 8px;
  background-color: #fff;
  border-radius: 10px;
  text-align: center;
  cursor: pointer;
}
.stateBox2 {
  margin-left: 20px;
  padding: 1px 8px;
  background-color: #fff;
  border-radius: 10px;
  text-align: center;
  cursor: pointer;
}
.stateBox2:hover {
  background-color: #dcdcdc;
}
/* 在线 */
.state1 {
  display: inline-block;
  height: 10px;
  width: 10px;
  border-radius: 50%;
  background-color: #8ee80e;
}
/* 离线 */
.state2 {
  display: inline-block;
  height: 10px;
  width: 10px;
  border-radius: 50%;
  background-color: #cacaca;
}
/* 忙碌 */
.state3 {
  display: inline-block;
  height: 10px;
  width: 10px;
  border-radius: 50%;
  background-color: #ff8c1e;
}
/* 退出登录 */
.state4 {
  display: inline-block;
  height: 10px;
  width: 10px;
  border-radius: 50%;
  background-color: #7e7e7e;
}
.stateText {
  font-size: 14px;
  margin-left: 5px;
}
/* 列表和信息 */
.infoBox {
  height: 90%;
  width: 100%;
  display: flex;
}
/* 用户列表大盒子 */
.userList {
  height: 100%;
  width: 300px;
  border-right: 1px solid #ccc;
  display: flex;
  flex-direction: column;
}
/* 用户列表 */
.userListBox {
  flex: 1;
  width: 100%;
  overflow: auto;
}
/* 信息外层盒子 */
.infoList {
  height: 100%;
  width: 72%;
}
/* 信息列表 */
.infoTop {
  height: 70%;
  width: 100%;
  border-bottom: 1px solid #ccc;
  padding: 10px;
  box-sizing: border-box;
  overflow: auto;
}
/* 对方发的信息样式 */
.chatInfoLeft {
  /* min-height: 70px; */
  margin-left: 10px;
  margin-top: 10px;
  display: flex;
}
.chatLeft {
  margin-left: 15px;
  flex: 1;
}
.chatLeft .text {
  color: #434343;
  margin-top: 8px;
  background-color: #e3e3e3;
  display: inline-block;
  padding: 6px 10px;
  border-radius: 10px;
  max-width: 50%;
  /* 忽略多余的空白，只保留一个空白 */
  white-space: normal;
  /* 换行显示全部字符 */
  word-break: break-all;
  white-space: pre-wrap;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
}

.chatImage{
  width: 5rem;
  height: 5rem;
}

/* 自己发的信息样式 */
.chatInfoRight {
  /* height: 70px; */
  margin-left: 10px;
  margin-top: 10px;
  display: flex;
  flex-direction: row-reverse;
}
.chatRight {
  margin-right: 15px;
  flex: 1;
  /* 用align-items把元素靠右对齐 */
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}
.chatRight .text {
  color: #434343;
  margin-top: 8px;
  background-color: #95ec69;
  display: inline-block;
  padding: 6px 10px;
  border-radius: 10px;
  max-width: 50%;
  /* 忽略多余的空白，只保留一个空白 */
  white-space: normal;
  /* 换行显示全部字符 */
  word-break: break-all;
  white-space: pre-wrap;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
}

.searchBox {
  padding: 4px 2px;
  border-bottom: 1px solid #ededed;
}
.input-with-select {
  width: 80%;
  margin-right: 2%;
}
/* 点击用户变色 */
.userFlexAct {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 70px;
  border-bottom: 1px solid #e8e8e8;
  cursor: pointer;
  background-color: #e8e8e8;
}
/* 用户默认颜色 */
.userFlex {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 70px;
  border-bottom: 1px solid #e8e8e8;
  cursor: pointer;
}
/* 用户名 */
.sender {
  width: 100px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 简略信息 */
.userInfo {
  width: 100px;
  font-size: 14px;
  color: #ccc;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 3px;
}

/* 滚动条样式 */
::-webkit-scrollbar {
  width: 5px;
  height: 10px;
}
::-webkit-scrollbar-thumb {
  background-color: #dbd9d9;
  border-radius: 3px;
}

.el-row {
    margin-bottom: 20px;
    /* &:last-child {
      margin-bottom: 0;
    } */
  }
  .el-col {
    border-radius: 4px;
  }
  .bg-purple-dark {
    background: #99a9bf;
  }
  .bg-purple {
    background: #d3dce6;
  }
  .bg-purple-light {
    background: #e5e9f2;
  }
  .grid-content {
    border-radius: 4px;
    min-height: 36px;
  }
  .row-bg {
    padding: 10px 0;
    background-color: #f9fafc;
  }
  .expression{
    width: 300px;
    height: 200px;
   float: left;
    overflow-x: hidden;
  }
  .expression_div{
    /* float: left; */
    width: 40px;
    height: 30px;
  }
</style>
